package org.dromara.demo.controller;

import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.domain.R;
import org.dromara.common.ratelimiter.annotation.RateLimiter;
import org.dromara.common.ratelimiter.enums.LimitType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;



/**
 * @Author 刘武贵
 * @Date 2024/8/15 22:00
 * @Description 功能描述：测试分布式限流样例
 */
@Slf4j
@RestController
@RequestMapping("/demo/rateLimiter")
public class RedisRateLimiterController {

    /**
     * 测试全局限流
     * 全局影响
     * 该方法用于演示接口访问限制，并返回操作成功的信息
     *
     * @param value 请求中的参数值，用于展示接口返回的具体内容
     * @return 返回一个结果对象，包含操作成功的信息和传入的value值
     */
    /**
     * 使用RateLimiter注解限制接口访问频率，每10秒内最多允许2次访问
     * 此限制旨在控制接口调用频率，防止恶意攻击或过度访问导致的服务不可用
     */
    @RateLimiter(count = 2, time = 10)
    @GetMapping("/test")
    public R<String> test(String value) {
        return R.ok("操作成功", value);
    }

    /**
     * 测试请求IP限流
     * 同一IP请求受影响
     * 该方法用于测试IP限流功能
     *
     * @param value 请求中的任意字符串参数，用于演示
     * @return 返回一个结果对象，包含操作状态和传入的value值
     */
    /**
     * 限流器注解，用于限制接口访问速率
     * 每10秒内，每个IP地址只允许访问2次
     */
    @RateLimiter(count = 2, time = 10, limitType = LimitType.IP)
    @GetMapping("/testip")
    public R<String> testip(String value) {
        return R.ok("操作成功", value);
    }

    /**
     * 测试集群实例限流
     * 启动两个后端服务互不影响
     * 该方法旨在测试集群限流功能
     *
     * @param value 请求中的参数值，用于展示接口能够接收并返回用户传递的值
     * @return 返回一个封装好的响应结果，包含操作成功的信息和用户传递的值
     */
    /**
     * 使用限流器注解限制接口访问速率
     * 该注解用于限制每10秒内最多访问该接口2次
     * 限流类型为集群限流，适用于集群部署场景
     */
    @RateLimiter(count = 2, time = 10, limitType = LimitType.CLUSTER)
    @GetMapping("/testcluster")
    public R<String> testcluster(String value) {
        return R.ok("操作成功", value);
    }

    /**
     * 测试请求IP限流(key基于参数获取)
     * 同一IP请求受影响
     * 该方法主要用于演示如何在Spring MVC中使用注解方式实现简单的限流功能
     *
     * 简单变量获取 #变量 复杂表达式 #{#变量 != 1 ? 1 : 0}
     * @param value 请求参数，用于生成限流key，防止不同参数值的请求相互影响
     * @return 返回操作成功的信息和传入的参数值
     */
    /**
     * 使用RateLimiter注解对特定IP的访问速率进行限制
     * 每10秒内，每个IP最多允许访问2次
     * 如果超过限制，请求将被拒绝，以防止潜在的滥用或攻击
     * 注解中的key属性引用了方法参数value，用于动态生成限流key
     * 这种方式可以灵活地根据不同的条件进行限流控制
     */
    @RateLimiter(count = 2, time = 10, limitType = LimitType.IP, key = "#value")
    @GetMapping("/testObj")
    public R<String> testObj(String value) {
        return R.ok("操作成功", value);
    }

}
